package cn.kais.drawer.bean;

import cn.kais.drawer.AxisUtil;
import cn.kais.drawer.UnitTools;
import cn.kais.drawer.UnitUtil;
import cn.kais.drawer.coms.BaseComs;
import cn.kais.drawer.coms.TextCom;
import cn.kais.drawer.menu.MenuBean;
import cn.kais.drawer.menu.MenuTextEven;
import cn.kais.drawer.unit.UnitText;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;

import java.awt.*;
import java.awt.font.TextAttribute;
import java.awt.geom.RoundRectangle2D;
import java.text.AttributedString;
import java.util.ArrayList;
import java.util.List;

public class BeanText extends BeanBasic {

    public String text;

    public int top;
    public int left;
    public int width;
    public int height;

    public Font font;   // 文本字体

    public Color color; // 文本颜色
    public Color bColor; // 背景颜色

    public int fontSize;    // 字体大小
    public String fontName; // 字体名称
    public boolean isBold;  // 是否加粗
    public boolean isItalic;// 是否斜体
    public String isUnderline; // 是否又下划线
    public String isCenterline; // 是否又中横线

    public boolean autoTurn; // 自动换行
    public boolean autoZoom; // 自动缩放

    public String textAlign;  // 水平对齐方式  左 中 右
    public String verticalAlign; // 垂直对齐方式 上 中 下

    public int borderWidth; // 边框宽度
    public Color borderColor; // 边框颜色
    public JSONObject borderRadius; // 圆角

    public String preText; // 前缀文本
    public String sufText; // 后缀文本
    public String lineBreak; // 换行符

    public boolean editDirection; // 横竖排列  false 横向排列 true 竖向排列
    public boolean spaceLineBreak; // 是否空格换行  true 开启 false 关闭

    /**
     * 文本对齐方式
     * 左右对齐 可以和 上下对齐/垂直居中 合并使用
     * 上下对齐 可以和 左右对齐/水平居中 合并使用
     * 水平居中 可以和 上下对齐/垂直居中 合并使用
     * 垂直居中 可以和 左右对齐/水平居中 合并使用
     */
    // 左中右
    public MenuTextEven even1 = MenuTextEven.CH;
    // 上中下
    public MenuTextEven even2 = MenuTextEven.CV;


    public Graphics2D sd; // 绘制

    /**
     * 空构造 只在组件拆分成小组件时使用
     */
    public BeanText() {
    }

    public BeanText(Graphics2D sd, JSONObject com) {
        menu = MenuBean.TEXT; // 之后可能会废弃
        this.sd = sd;
        this.top = com.getInteger("top");
        this.left = com.getInteger("left");
        this.width = com.getInteger("width");
        this.height = com.getInteger("height");

        this.text = com.getString("text");

        this.color = UnitUtil.toColor(com.getString("fontColor"));
        this.bColor = UnitUtil.toColor(com.getString("bgColor"));

        this.fontName = com.getString("font");
        this.fontSize = com.getInteger("fontSize");
        this.isBold = com.getBoolean("isBold");
        this.isItalic = com.getBoolean("isItaly");
        this.font = UnitUtil.toFont(this.fontName, this.fontSize, this.isBold, this.isItalic);

        this.isUnderline = com.getString("isUnderline");
        this.isCenterline = com.getString("isCenterline");

        this.autoTurn = com.getBooleanValue("autoTurn");
        this.autoZoom = com.getBooleanValue("autoZoom");

        // flex-start center flex-end
        this.textAlign = com.getString("textAlign");
        this.verticalAlign = com.getString("verticalAlign");

        this.borderWidth = com.getIntValue("borderWidth");
        String bColor = com.getString("borderColor");
        if (StringUtils.isNotBlank(bColor)) {
            this.borderColor = UnitUtil.toColor(bColor);
        }
        this.borderRadius = com.getJSONObject("borderRadius");

        this.preText = com.getString("preText");
        this.sufText = com.getString("sufText");
        this.lineBreak = com.getString("lineBreak");

        this.editDirection = com.getBooleanValue("editDirection");
        this.spaceLineBreak = com.getBooleanValue("spaceLineBreak");

        this.create();
    }

    private void create() {
        // 区域框
        if (this.isShowBorder) {
            new BeanBorder(this.sd, this.top, this.left, this.width, this.height);
        }
        // 背景
//        sd.setColor(this.bColor);
//        sd.fillRect(this.left, this.top, this.width, this.height);
        int LT = borderRadius.getIntValue("leftTop");       // 左上
        int LB = borderRadius.getIntValue("leftBottom");    // 左下
        int RT = borderRadius.getIntValue("rightTop");      // 右上
        int RB = borderRadius.getIntValue("rightBottom");   // 右下

        int mRadius = UnitTools.onGetMaxRadius(LT, LB, RT, RB) * 2;         // 取最大圆角
        int wRadius = this.width / 2;   // 宽半径
        int hRadius = this.height / 2;  // 高半径
//        System.out.println("圆角：" + mRadius);

        sd.setColor(this.bColor);
        sd.fill(new RoundRectangle2D.Double(this.left, this.top, this.width, this.height, mRadius, mRadius));
        if (LT <= 0) { // 恢复左上角为直角
//            System.out.println("恢复左上角为直角");
            sd.fillRect(this.left, this.top, wRadius, hRadius);
        }
        if (LB <= 0) { // 恢复左下角为直角
//            System.out.println("恢复左下角为直角");
            sd.fillRect(this.left, this.top + hRadius, wRadius, hRadius);
        }
        if (RT <= 0) { // 恢复右上角为直角
//            System.out.println("恢复右上角为直角");
            sd.fillRect(this.left + wRadius, this.top, wRadius, hRadius);
        }
        if (RB <= 0) { // 恢复右下角为直角
//            System.out.println("恢复右下角为直角");
            sd.fillRect(this.left + wRadius, this.top + hRadius, wRadius, hRadius);
        }

        // 文本
        String text0 = UnitText.doFixText(this.text, this.preText, this.sufText);
        List<String> items = UnitText.doSubText(text0, this.lineBreak);
        JSONObject wh = new JSONObject();
        wh.put("maxWei", 0);
        wh.put("maxHei", 0);
        List<BaseComs> coms = new ArrayList<>();
        if (this.editDirection) {
            // 竖向排列
            this.doCountWeiHeiAddComsOnVer(items, coms, wh);
        } else {
            // 横向排列
            this.doCountWeiHeiAddComsOnHor(items, coms, wh);
        }
        System.out.println(coms.size());
        System.out.println(wh.toJSONString());
        int maxWei = wh.getInteger("maxWei");
        int maxHei = wh.getInteger("maxHei");
        // 分别绘制
        for (int i = 0; i < coms.size(); i++) {
            BaseComs base = coms.get(i);
            if (null != base) {
                TextCom text = (TextCom) base;
                int x = 0;
                int xx = 0;
                switch (this.textAlign) {
                    case "flex-start": // 左对齐
                        // 1.正常绘制
                        break;
                    case "flex-end": // 右对齐
                        // 1.计算文本宽度 left = left + (width - fontwidth)
                        xx = this.width - maxWei;
                        break;
                    case "center": // 水平居中
                        // 1.计算文本宽度 left = left + ((width - fontwidth) / 2)
                        xx = (this.width - maxWei) / 2;
                        break;
                }

                int y = AxisUtil.doCountTextItemY(i, coms);
                int yy = 0;
                switch (this.verticalAlign) {
                    case "flex-start": // 上对齐
                        // 1.正常绘制
                        break;
                    case "flex-end": // 下对齐
                        // 1.计算文本高度 top = (top + fontsize) + (height - fontsize)
                        yy = this.height - maxHei;
                        break;
                    case "center": // 垂直居中
                        // 1.计算文本高度 top = (top + fontsize) + ((height - fontsize) / 2)
                        yy = (this.height - maxHei) / 2;
                        break;
                }
                // 绘制
                this.sd.drawString(text.attr.getIterator(), x + xx + this.left, y + yy + this.top + text.height);
            }
        }

    }

    /**
     * Json 列表转换 组件列表 并计算出最大宽度 高度
     * 竖向
     *
     * @param items Json 列表
     * @param coms  组件 列表
     * @param wh    最大宽度 最大高度
     */
    private void doCountWeiHeiAddComsOnVer(List<String> items, List<BaseComs> coms, JSONObject wh) {
        System.out.println("------------");
        System.out.println(this.width);
        System.out.println(this.height);
        int maxWei = 0;
        int maxHei = 0;
        coms.clear();
        for (String item : items) {
//            System.out.println(item);
            for (int i = 0; i < item.length(); i++) {
                char c = item.charAt(i);
                TextCom com = onCreateText(String.valueOf(c));
                System.out.println(String.valueOf(c));
                maxHei = maxHei + com.height;
                if (com.width > maxWei) maxWei = com.width;
                // 如果当前文本宽度 小于 文本框宽度 无需自动换行
                coms.add(com);
            }
        }
        wh.put("maxWei", maxWei);
        wh.put("maxHei", maxHei);
        System.out.println("------------");
    }

    /**
     * Json 列表转换 组件列表 并计算出最大宽度 高度
     * 横向
     *
     * @param items Json 列表
     * @param coms  组件 列表
     * @param wh    最大宽度 最大高度
     */
    private void doCountWeiHeiAddComsOnHor(List<String> items, List<BaseComs> coms, JSONObject wh) {
        int maxWei = 0;
        int maxHei = 0;
        coms.clear();
        for (String item : items) {
            TextCom com = onCreateText(item);
            if (this.autoTurn) {  // 自动换行
                if (com.width < this.width) {
                    maxHei = maxHei + com.height;
                    if (com.width > maxWei) maxWei = com.width;
                    // 如果当前文本宽度 小于 文本框宽度 无需自动换行
                    coms.add(com);
                } else {
                    if (this.width > maxWei) maxWei = this.width;
                    if (this.spaceLineBreak) {
                        List<String> list = new ArrayList<>();
                        StringBuilder cs = new StringBuilder();
                        for (int i = 0; i < item.length(); i++) {
                            char c = item.charAt(i);
                            if (c == ' ') {
                                list.add(cs.toString());
                                list.add(" ");
                                cs = new StringBuilder();
                            } else if (i == item.length() - 1) {
                                cs.append(c);
                                list.add(cs.toString());
                                cs = new StringBuilder();
                            } else {
                                cs.append(c);
                            }
                        }
                        // 如果当前文本宽度 大于 文本框宽度 重新计算 并拆分
                        int cws = 0;
                        StringBuilder cts = new StringBuilder();
                        for (int i = 0; i < list.size(); i++) {
                            String c = list.get(i);
                            FontMetrics metrics = this.sd.getFontMetrics(this.font);
                            int cw = metrics.stringWidth(String.valueOf(c));
                            cws = cws + cw;
                            if (cws >= this.width) {
                                TextCom sc = onCreateText(cts.toString());
                                maxHei = maxHei + sc.height;
                                coms.add(sc);
                                cws = cw;
                                cts = new StringBuilder();
                                cts.append(c);
                            } else {
                                cts.append(c);
                            }
                            if (i == list.size() - 1) {
                                TextCom sc = onCreateText(cts.toString());
                                maxHei = maxHei + sc.height;
                                coms.add(sc);
                                cws = 0;
                                cts = new StringBuilder();
                                cts.append(c);
                            }
                        }
                    } else {
                        // 如果当前文本宽度 大于 文本框宽度 重新计算 并拆分
                        int cws = 0;
                        StringBuilder cts = new StringBuilder();
                        for (int i = 0; i < item.length(); i++) {
                            char c = item.charAt(i);
                            FontMetrics metrics = this.sd.getFontMetrics(this.font);
                            int cw = metrics.stringWidth(String.valueOf(c));
                            cws = cws + cw;
                            if (cws >= this.width) {
                                TextCom sc = onCreateText(cts.toString());
                                maxHei = maxHei + sc.height;
                                coms.add(sc);
                                cws = 0;
                                cts = new StringBuilder();
                                cts.append(c);
                            } else {
                                cts.append(c);
                            }
                            if (i == item.length() - 1) {
                                TextCom sc = onCreateText(cts.toString());
                                maxHei = maxHei + sc.height;
                                coms.add(sc);
                            }
                        }
                    }
                }
            } else {
                if (this.autoZoom && (com.width > this.width)) { // 自动缩放  只自动缩小
                    System.out.println("缩小");
                    double ratio = (double) this.width / com.width;
                    double newSize = this.fontSize * ratio;
                    this.fontSize = (int) newSize;
                    this.font = UnitUtil.toFont(this.fontName, this.fontSize, this.isBold, this.isItalic);
                    TextCom sc = onCreateText(item);
//                    TextCom sc = this.onResetFontSize(item, "sub");
                    maxWei = sc.width;
                    maxHei = maxHei + sc.height;
                    coms.add(sc);

//                    if (com.width > this.width) {
//                        System.out.println("缩小");
//                        TextCom sc = this.onResetFontSize(item, "sub");
//                        maxWei = sc.width;
//                        maxHei = maxHei + sc.height;
//                        coms.add(sc);
//                    } else {
//                        System.out.println("放大");
//                        TextCom sc = this.onResetFontSize(item, "add");
//                        maxWei = sc.width;
//                        maxHei = maxHei + sc.height;
//                        coms.add(sc);
//                    }
                } else { // 多余裁剪
                    if (com.width > this.width) {
                        int cws = 0;
                        StringBuilder cts = new StringBuilder();
                        for (int i = 0; i < item.length(); i++) {
                            char c = item.charAt(i);
                            FontMetrics metrics = this.sd.getFontMetrics(this.font);
                            int cw = metrics.stringWidth(String.valueOf(c));
                            cws = cws + cw;
                            if (cws >= this.width) {
                                TextCom sc = onCreateText(cts.toString());
                                maxWei = cws;
                                maxHei = maxHei + sc.height;
                                coms.add(sc);
                                break;
                            } else {
                                cts.append(c);
                            }
                        }
                    } else {
                        maxWei = com.width;
                        maxHei = maxHei + com.height;
                        coms.add(com);
                    }
                }
            }
        }
        wh.put("maxWei", maxWei);
        wh.put("maxHei", maxHei);
    }

    /**
     * 每段 独立文本组件
     *
     * @param text 内容
     * @return 文本组件
     */
    private TextCom onCreateText(String text) {
        // 字体
        FontMetrics metrics = this.sd.getFontMetrics(this.font);
        int fontHeight = metrics.getAscent() - metrics.getDescent() - metrics.getLeading() + 6;
        int fontWidth = metrics.stringWidth(text);
        // 文本
        AttributedString as = new AttributedString(text);
        as.addAttribute(TextAttribute.FONT, this.font); // 文本字体
        as.addAttribute(TextAttribute.FOREGROUND, this.color); // 文本颜色
        if (null != isUnderline && !isUnderline.equals("none")) { // 下划线
            as.addAttribute(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
        }
        if (null != isCenterline && !isCenterline.equals("none")) { // 中横线
            as.addAttribute(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
        }
        return new TextCom(as, fontWidth, fontHeight, 1);
    }

    /**
     * 缩放时重置字体
     *
     * @param text  文本
     * @param state sub 减 add 加
     */
    private TextCom onResetFontSize(String text, String state) {
        if (state.equals("sub")) {
            this.fontSize = this.fontSize - 1;
        }
        if (state.equals("add")) {
            this.fontSize = this.fontSize + 1;
        }
        this.font = UnitUtil.toFont(this.fontName, this.fontSize, this.isBold, this.isItalic);
        FontMetrics metrics = this.sd.getFontMetrics(this.font);
        int cw = metrics.stringWidth(text);
        System.out.println(this.fontSize);
        System.out.println(cw + "=====" + this.width);
        if (state.equals("sub") && cw > this.width) {
            System.out.println("缩小");
            return this.onResetFontSize(text, state);
        } else if (state.equals("add") && cw < this.width) {
            System.out.println("放大");
            return this.onResetFontSize(text, state);
        } else {
            return onCreateText(text);
        }
    }


}
